//---------------------------------------------------------------------------
//
// Copyright (c) 2013 Realtek Semiconductor, Inc. All rights reserved.
// 
//---------------------------------------------------------------------------
// Description:
//		P2P Service interface for upper layers
//

#ifndef __INC_P2P_SVC_TYPE_H
#define __INC_P2P_SVC_TYPE_H

//-----------------------------------------------------------------------------
// P2PSVC Version
//-----------------------------------------------------------------------------

// The current support version of WFD
#define	P2PSVC_MIN_SUPPORT_VER							0
#define	P2PSVC_MAX_SUPPORT_VER							0

#define	P2PSVC_OBJECT_VERSION_DONT_CARE					0
#define	P2PSVC_OBJECT_VERSION_INVLAID					0xFFFFFFFF

//-----------------------------------------------------------------------------
// Reason string
//-----------------------------------------------------------------------------
typedef u4Byte P2PSVC_REASON, *PP2PSVC_REASON;

#define P2PSVC_REASON_NONE								((P2PSVC_REASON)0x00000000)
#define P2PSVC_REASON_PEER_UNRECOGNIZED					((P2PSVC_REASON)0x00000001)
#define P2PSVC_REASON_ADV_ID_MISMATCH					((P2PSVC_REASON)0x00000002)
#define P2PSVC_REASON_CONFIG_METHOD_MISMATCH			((P2PSVC_REASON)0x00000003)
#define P2PSVC_REASON_INVALID_CONN_CAP					((P2PSVC_REASON)0x00000004)
#define P2PSVC_REASON_NO_MATCHING_SVC					((P2PSVC_REASON)0x00000005)
#define P2PSVC_REASON_REQ_SVC_NOT_AVAILABLE				((P2PSVC_REASON)0x00000006)
#define P2PSVC_REASON_MISS_ATTR_STATUS					((P2PSVC_REASON)0x00000007)
#define P2PSVC_REASON_MISS_ATTR_CONN_CAP				((P2PSVC_REASON)0x00000008)
#define P2PSVC_REASON_MISS_ATTR_GRP_ID					((P2PSVC_REASON)0x00000009)
#define P2PSVC_REASON_MISS_ATTR_INTF_ADDR				((P2PSVC_REASON)0x0000000A)
#define P2PSVC_REASON_MISS_ATTR_OP_CHNL					((P2PSVC_REASON)0x0000000B)
#define P2PSVC_REASON_MISS_ATTR_SESSION_ID_INFO			((P2PSVC_REASON)0x0000000C)
#define P2PSVC_REASON_MISS_ATTR_DEV_INFO				((P2PSVC_REASON)0x0000000D)

#define P2PSVC_DEFINE_REASON(__reasonStr) (#__reasonStr)

static char* P2PSVC_REASON_STR_TAB[] = 
{
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_NONE),						// 0x00000000
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_PEER_UNRECOGNIZED),			// 0x00000001
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_ADV_ID_MISMATCH),			// 0x00000002
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_CONFIG_METHOD_MISMATCH),		// 0x00000003
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_INVALID_CONN_CAP),			// 0x00000004
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_NO_MATCHING_SVC),			// 0x00000005
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_REQ_SVC_NOT_AVAILABLE),		// 0x00000006
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_STATUS),			// 0x00000007
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_CONN_CAP),			// 0x00000008
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_GRP_ID),			// 0x00000009
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_INTF_ADDR),		// 0x0000000A
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_OP_CHNL),			// 0x0000000B
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_SESSION_ID_INFO),	// 0x0000000C
	P2PSVC_DEFINE_REASON(P2PSVC_REASON_MISS_ATTR_DEV_INFO),			// 0x0000000D
};

//-----------------------------------------------------------------------------
// Object Header
//-----------------------------------------------------------------------------

#define P2PSVC_OBJ_HDR_ID_BMP_DATA						((u4Byte)BIT28)
#define P2PSVC_OBJ_HDR_ID_BMP_ACTION					((u4Byte)BIT29)
#define P2PSVC_OBJ_HDR_ID_BMP_INDICATE					((u4Byte)BIT30)
#define P2PSVC_OBJ_HDR_ID_BMP_RSVD_2					((u4Byte)BIT31)

#define P2PSVC_OBJ_HDR_ID_UNKNOWN						((u4Byte)0x00000000)

// Data obj ID
#define P2PSVC_OBJ_HDR_ID_DATA_UNKNOWN					((u4Byte)0x00000000 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_OBJ_LIST					((u4Byte)0x00000001 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_BENABLE					((u4Byte)0x00000002 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME					((u4Byte)0x00000003 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_NAME_HASH			((u4Byte)0x00000004 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO_REQ				((u4Byte)0x00000005 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_INFO					((u4Byte)0x00000006 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_AUTO_ACCEPT			((u4Byte)0x00000007 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_STATUS				((u4Byte)0x00000008 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_ADV_ID					((u4Byte)0x00000009 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_DEV_ADDR					((u4Byte)0x0000000A | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SEARCH_ID				((u4Byte)0x0000000B | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_DEV_NAME					((u4Byte)0x0000000C | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_DESC_LIST			((u4Byte)0x0000000D | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SESSION_INFO				((u4Byte)0x0000000E | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_NETWORK_ROLE				((u4Byte)0x0000000F | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_CONN_CAP					((u4Byte)0x00000010 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SESSION_ID				((u4Byte)0x00000011 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_USER_ACCEPTED			((u4Byte)0x00000012 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SVC_COUNT				((u4Byte)0x00000013 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_P2P_STATUS				((u4Byte)0x00000014 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_P2P_ATTRIBUTES			((u4Byte)0x00000015 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_SSID						((u4Byte)0x00000016 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_INTF_ADDR				((u4Byte)0x00000017 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_OP_CHNL					((u4Byte)0x00000018 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_CONFIG_METHOD			((u4Byte)0x00000019 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_DEFERRED					((u4Byte)0x0000001A | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_IS_SD_DONE				((u4Byte)0x0000001B | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_IS_PERSISTENT			((u4Byte)0x0000001C | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_CONN_ACTION				((u4Byte)0x0000001D | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_REASON					((u4Byte)0x0000001E | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_NETWORK_CONFIG			((u4Byte)0x0000001F | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_GET_NETWORK_CONFIG_PIN	((u4Byte)0x00000020 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_NETWORK_CONFIG_PIN		((u4Byte)0x00000021 | P2PSVC_OBJ_HDR_ID_BMP_DATA)
#define P2PSVC_OBJ_HDR_ID_DATA_GRP_DEV_ADDR				((u4Byte)0x00000022 | P2PSVC_OBJ_HDR_ID_BMP_DATA)

// Action obj ID
#define P2PSVC_OBJ_HDR_ID_ACT_UNKNOWN					((u4Byte)0x00000000 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_ENABLE					((u4Byte)0x00000001 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_SEEK						((u4Byte)0x00000002 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_CANCEL_SEEK				((u4Byte)0x00000003 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_ADVERTISE					((u4Byte)0x00000004 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_CANCEL_ADVERTISE			((u4Byte)0x00000005 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_SVC_STATUS				((u4Byte)0x00000006 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_PD_REQ					((u4Byte)0x00000007 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_FOPD_REQ					((u4Byte)0x00000008 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)
#define P2PSVC_OBJ_HDR_ID_ACT_CONN_CAP					((u4Byte)0x00000009 | P2PSVC_OBJ_HDR_ID_BMP_ACTION)

// Indication obj ID
#define P2PSVC_OBJ_HDR_ID_INDIC_UNKNOWN							((u4Byte)0x00000000 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_PD_REQ_SENT				((u4Byte)0x00000100 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_ON_PD_RSP				((u4Byte)0x00000101 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_ON_FOPD_REQ				((u4Byte)0x00000102 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_FOPD_RSP_SENT			((u4Byte)0x00000103 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_PD_REQ_SEND_FAILED		((u4Byte)0x00000104 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_PD_TOPOLOGY				((u4Byte)0x00000105 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_ON_BAD_PD_RSP			((u4Byte)0x00000106 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_INITOR_ON_BAD_FOPD_REQ			((u4Byte)0x00000107 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_ON_PD_REQ				((u4Byte)0x00000200 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_PD_RSP_SENT				((u4Byte)0x00000201 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_FOPD_REQ_SENT			((u4Byte)0x00000202 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_ON_FOPD_RSP				((u4Byte)0x00000203 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_FOPD_REQ_SEND_FAILED		((u4Byte)0x00000204 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_PD_TOPOLOGY				((u4Byte)0x00000205 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_ON_BAD_PD_REQ			((u4Byte)0x00000206 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_RSPDOR_ON_BAD_FOPD_RSP			((u4Byte)0x00000207 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_REQ_SENT					((u4Byte)0x00000400 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_RSP_RECVD					((u4Byte)0x00000401 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_CONF_SENT					((u4Byte)0x00000402 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_REQ_SEND_FAILED			((u4Byte)0x00000403 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_CONF_SEND_FAILED			((u4Byte)0x00000404 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_REQ_RECVD					((u4Byte)0x00000800 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_RSP_SENT					((u4Byte)0x00000801 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_CONF_RECVD					((u4Byte)0x00000802 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)
#define P2PSVC_OBJ_HDR_ID_INDIC_NEGO_RSP_SEND_FAILED			((u4Byte)0x00000803 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_OBJ_HDR_ID_INDIC_SEARCH_RESULT					((u4Byte)0x00000C00 | P2PSVC_OBJ_HDR_ID_BMP_INDICATE)

#define P2PSVC_MAX_OBJ_LIST_ENTRIES								32

#define P2PSVC_WIFI_WFDS_SERVICE_NAME							"org.wi-fi.wfds"

#define P2PSVC_WIFI_WFDS_MAX_SERVICE_NAME_LEN					255


typedef struct _P2PSVC_SVC_NAME_HASH_TAB
{
	WCHAR							svcName[256];
	UCHAR 							hash[6];
}P2PSVC_SVC_NAME_HASH_TAB, *PP2PSVC_SVC_NAME_HASH_TAB;

static P2PSVC_SVC_NAME_HASH_TAB gP2PSVC_NameHashTab[] = 
{
	{L"org.wi-fi.wfds",				{0x6d, 0xb8, 0x71, 0x03, 0x11, 0xf8}},
		
	{L"org.wi-fi.wfds.send.rx",		{0xeb, 0xac, 0xb9, 0x5f, 0x37, 0x4e}},
	{L"org.wi-fi.wfds.send.tx",		{0x28, 0x6d, 0xef, 0xe4, 0x6d, 0xd5}},

	{L"org.wi-fi.wfds.play.rx",		{0x20, 0xcd, 0xdd, 0x02, 0x10, 0xca}},
	{L"org.wi-fi.wfds.play.tx",		{0xe8, 0x19, 0x14, 0x6c, 0x33, 0xe3}},

	{L"org.wi-fi.wfds.display.rx",	{0x9e, 0x26, 0x60, 0x5a, 0x4f, 0xd4}},
	{L"org.wi-fi.wfds.display.tx",	{0x0b, 0x8c, 0x3c, 0xd4, 0x22, 0x05}},

	{L"org.wi-fi.wfds.print.rx",	{0xe8, 0x52, 0xf0, 0xab, 0xd5, 0x8b}},
	{L"org.wi-fi.wfds.print.tx",	{0x94, 0x63, 0x35, 0xc3, 0xdf, 0xd7}},
	//------------------------------------------------------------
	{L"", {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
};

#pragma pack(1)
typedef struct _P2PSVC_OBJ_LIST
{
	// Hdr
	RT_OBJECT_HEADER				hdr;	// len is form Value to the end of the structure including the var len field
	
	// Fixed
	u4Byte							nObjs;
	u4Byte							ObjTab[P2PSVC_MAX_OBJ_LIST_ENTRIES];
	
	// Var
	u1Byte							varStart[1];
}P2PSVC_OBJ_LIST, *PP2PSVC_OBJ_LIST;
#pragma pack()

// Return ptr to the obj in the obj list of a specifc index
// If index is beyond the # of objs in the list, return NULL
#define P2PSVC_OBJ_LIST_GET_OBJ(__pObjList, __index) \
	(((__index) < ((__pObjList)->nObjs)) ? \
	(((PRT_OBJECT_HEADER)(((__pObjList)->varStart) + ((__pObjList)->ObjTab)[(__index)]))) : \
	(NULL))

// Return the length of the total obj list structure including the var field
// Assume the obj list is valid
#define P2PSVC_OBJ_LIST_LEN(__pObjList) ((FIELD_OFFSET(RT_OBJECT_HEADER, Value) + ((__pObjList)->hdr.Length)))

#define P2PSVC_OBJ_LIST_VAR_LEN(__pObjList) (((__pObjList)->hdr.Length) - (FIELD_OFFSET(P2PSVC_OBJ_LIST, varStart) - FIELD_OFFSET(RT_OBJECT_HEADER, Value)))

#define P2PSVC_OBJ_LIST_INIT(__pObjList, __type, __id, __ver)\
{\
	RT_ASSIGN_OBJECT_HEADER(&(__pObjList)->hdr, __type, __id, __ver, FIELD_OFFSET(P2PSVC_OBJ_LIST, varStart) - FIELD_OFFSET(RT_OBJECT_HEADER, Value));\
	(__pObjList)->nObjs = 0;\
}

//
// P2P Services connection capability bitmap
//
#define P2PSVC_CONN_CAP_BMP_NONE		((u1Byte)0)
#define P2PSVC_CONN_CAP_BMP_NEW			((u1Byte)BIT0)
#define P2PSVC_CONN_CAP_BMP_CLI			((u1Byte)BIT1)
#define P2PSVC_CONN_CAP_BMP_GO			((u1Byte)BIT2)

//
// P2P Services connection methods
//
#define P2PSVC_CONN_METHOD_NONE			((u4Byte)0x00000000)
#define P2PSVC_CONN_METHOD_INIT_NEGO	((u4Byte)0x00000001)		// Init GO Negotiation
#define P2PSVC_CONN_METHOD_WAIT_NEGO	((u4Byte)0x00000002)		// Wait GO Negotiation
#define P2PSVC_CONN_METHOD_JOIN_BY		((u4Byte)0x00000003)		// Peer will join existing group
#define P2PSVC_CONN_METHOD_JOIN			((u4Byte)0x00000004)		// Join existing group peer is hosting
#define P2PSVC_CONN_METHOD_AUTO_GO		((u4Byte)0x00000005)		// Start Auto GO for peer to join


#endif // #ifndef __INC_P2P_SVC_TYPE_H


